package com.wyz.saas.app.set

import android.app.AlertDialog
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.InputType
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.appcompat.widget.Toolbar
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.atom.module.mvvm.base.AbstractViewModelFactory
import com.atom.module.mvvm.base.EmptyModel
import com.atom.module.mvvm.wight.recycler.multi.MultiRecyclerAdapter
import com.atom.module.mvvm.wight.recycler.multi.MultiRecyclerAdapterListener
import com.wyz.saas.api.set.AppSetDescriptor
import com.wyz.saas.app.R
import com.wyz.saas.app.databinding.FragmentAppSetBinding
import com.wyz.saas.common.base.AbstractApiToolbarFragment
import com.wyz.saas.common.impl.EmptyApiModel
import com.wyz.saas.common.map.MapViewModel
import com.wyz.saas.common.set.*
import com.wyz.saas.common.utils.otherwise
import com.wyz.saas.common.utils.yes

class AppSetDescriptorFragment
    : AbstractApiToolbarFragment<FragmentAppSetBinding, SetViewModel>() {

    private val appSets: MutableMap<String, MutableList<AppSetDescriptor>> = mutableMapOf()

    override fun initContentView(
        inflater: LayoutInflater?,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): Int = R.layout.fragment_app_set

    override fun initViewModel(): SetViewModel {
        val factory = object : AbstractViewModelFactory() {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                if (modelClass.isAssignableFrom(MapViewModel::class.java)) {
                    return SetViewModel(EmptyApiModel()) as T
                }
                return modelClass.newInstance()
            }
        }
        return ViewModelProvider(this, factory).get(SetViewModel::class.java)
    }

    abstract class BaseViewHolder<T : AppSetDescriptor>(viewBinding: ViewDataBinding) :
        MultiRecyclerAdapter.ViewHolder<T>(viewBinding) {

        var icon: ImageView? = null
        var label: TextView? = null

        init {
            icon = itemView.findViewById(R.id.app_set_icon)
            label = itemView.findViewById(R.id.app_set_label)
        }

        override fun onBind(data: T) {
            icon?.setImageBitmap(data.getIcon())
            label?.text = data.getLabel()
        }
    }

    inner class ButtonViewHolder(viewBinding: ViewDataBinding) :
        BaseViewHolder<AbstractAppSetDescriptorButton>(viewBinding) {
        override fun onBind(data: AbstractAppSetDescriptorButton) {
            super.onBind(data)
            itemView.setOnClickListener {
                data.onClick(this@AppSetDescriptorFragment, it)
            }
        }
    }

    inner class DoubleViewHolder(viewBinding: ViewDataBinding) :
        BaseViewHolder<AbstractAppSetDescriptorDouble>(viewBinding) {
        var text: TextView? = null

        init {
            text = itemView.findViewById(R.id.app_set_double)
        }

        override fun onBind(data: AbstractAppSetDescriptorDouble) {
            super.onBind(data)
            text?.text = data.getValue().toString()
            text?.setOnClickListener {
                showInputDialog(
                    it,
                    InputType.TYPE_NUMBER_FLAG_DECIMAL,
                    data.getLabel(), BitmapDrawable(resources, data.getIcon()),
                    object : InputListener {
                        override fun input(value: Editable) {
                            data.setValue(value.toString().toDouble())
                            text?.text = value
                        }
                    }
                )
            }
        }
    }

    inner class BooleanViewHolder(viewBinding: ViewDataBinding) :
        BaseViewHolder<AbstractAppSetDescriptorBoolean>(viewBinding) {
        var radioGroup: RadioGroup? = null
        var trueButton: RadioButton? = null
        var falseButton: RadioButton? = null

        init {
            radioGroup = itemView.findViewById(R.id.app_set_boolean)
            trueButton = itemView.findViewById(R.id.app_set_boolean_true)
            falseButton = itemView.findViewById(R.id.app_set_boolean_false)
        }

        override fun onBind(data: AbstractAppSetDescriptorBoolean) {
            super.onBind(data)
            trueButton?.text = data.getValueTip(true)
            falseButton?.text = data.getValueTip(false)
            (data.getValue() as Boolean).yes {
                radioGroup?.check(R.id.app_set_boolean_true)
            }.otherwise {
                radioGroup?.check(R.id.app_set_boolean_false)
            }
            radioGroup?.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
                if (checkedId == R.id.app_set_boolean_true) {
                    data.setValue(true)
                } else if (checkedId == R.id.app_set_boolean_false) {
                    data.setValue(false)
                }
            }
        }
    }

    inner class IntViewHolder(viewBinding: ViewDataBinding) :
        BaseViewHolder<AbstractAppSetDescriptorInt>(viewBinding) {
        var seekBar: SeekBar? = null

        init {
            seekBar = itemView.findViewById(R.id.app_set_int)
        }

        override fun onBind(data: AbstractAppSetDescriptorInt) {
            super.onBind(data)
            seekBar?.max = data.max()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                seekBar?.min = data.min()
            }
            seekBar?.progress = data.getValue() as Int
            seekBar?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
                override fun onProgressChanged(
                    seekBar: SeekBar?,
                    progress: Int,
                    fromUser: Boolean
                ) {
                    Log.e("AppSetDescriptor", " progress = $progress")
                }

                override fun onStartTrackingTouch(seekBar: SeekBar?) {

                }

                override fun onStopTrackingTouch(seekBar: SeekBar?) {
                    data.setValue(seekBar?.progress)
                }

            })
        }
    }

    inner class TextViewHolder(viewBinding: ViewDataBinding) :
        BaseViewHolder<AbstractAppSetDescriptorText>(viewBinding) {

        var text: TextView? = null

        init {
            text = itemView.findViewById(R.id.app_set_text)
        }

        override fun onBind(data: AbstractAppSetDescriptorText) {
            super.onBind(data)
            text?.text = data.getValue() as String
            text?.setOnClickListener {
                showInputDialog(
                    it,
                    InputType.TYPE_CLASS_TEXT,
                    data.getLabel(),
                    BitmapDrawable(resources, data.getIcon()),
                    object : InputListener {
                        override fun input(value: Editable) {
                            data.setValue(value.toString())
                            text?.text = value
                        }
                    })
            }
        }
    }

    interface InputListener {
        fun input(value: Editable)
    }

    private fun showInputDialog(
        view: View,
        type: Int,
        msg: String,
        icon: Drawable?,
        listener: InputListener
    ) {
        val input = EditText(view.context)
        input.inputType = type
        AlertDialog.Builder(view.context)
            .setMessage(msg)
            .setIcon(icon)
            .setView(input)
            .setPositiveButton("确定") { dialog, w ->
                listener.input(input.text)
                dialog.dismiss()
            }
            .setNegativeButton("取消") { dialog, w ->
                dialog.dismiss()

            }.create().show()
    }

    private val adapter = object : MultiRecyclerAdapter<AppSetDescriptor>() {

        override fun getItemViewType(position: Int, data: AppSetDescriptor): Int {
            if (data is AbstractAppSetDescriptorInt) {
                return R.layout.cell_app_set_int
            }
            if (data is AbstractAppSetDescriptorBoolean) {
                return R.layout.cell_app_set_boolean
            }
            if (data is AbstractAppSetDescriptorDouble) {
                return R.layout.cell_app_set_double
            }
            if (data is AbstractAppSetDescriptorText) {
                return R.layout.cell_app_set_text
            }
            return R.layout.cell_app_set
        }

        override fun onCreateMultiViewHolder(
            binding: ViewDataBinding,
            viewType: Int
        ): ViewHolder<AppSetDescriptor> {
            val simpleViewHolder = when (viewType) {
                R.layout.cell_app_set_int -> IntViewHolder(binding)
                R.layout.cell_app_set_boolean -> BooleanViewHolder(binding)
                R.layout.cell_app_set_text -> TextViewHolder(binding)
                R.layout.cell_app_set_double -> DoubleViewHolder(binding)
                else -> ButtonViewHolder(binding)
            }
            return simpleViewHolder as BaseViewHolder<AppSetDescriptor>
        }

    }

    override fun initData(view: View?) {
        super.initData(view)
        view?.also { root ->
            val findViewById = root.findViewById<RecyclerView>(R.id.app_set_list)
            findViewById.layoutManager = LinearLayoutManager(context)
            findViewById.adapter = adapter
            adapter.listener = object : MultiRecyclerAdapterListener<AppSetDescriptor>() {
                override fun onMultiItemClick(viewHolder: MultiRecyclerAdapter.ViewHolder<AppSetDescriptor>) {
                    viewHolder.mData?.also {
                        if (it is AbstractAppSetDescriptorButton) {
                            it.onClick(this@AppSetDescriptorFragment, viewHolder.itemView)
                        }
                    }
                }
            }
        }
    }

    override fun initToolbar(toolbar: Toolbar?) {
        super.initToolbar(toolbar)
        toolbar?.title = "设置"
    }


    override fun onFirst() {
        super.onFirst()
        view?.post {
            adapter.addAll(loadData())
        }
    }

    private fun loadData(): List<AppSetDescriptor> {
        val mutableList = mutableListOf<AppSetDescriptor>()
        val apiImplContext = apiContext()
        for (cls in apiImplContext.getApis(AppSetDescriptor::class.java)) {
            try {
                val appset = apiImplContext.newApi(cls)
                if (appset != null) {
                    mutableList.add(appset)
                }
            } catch (ignored: Exception) {
            }
        }
        mutableList.sortWith(object : Comparator<AppSetDescriptor> {
            override fun compare(o1: AppSetDescriptor?, o2: AppSetDescriptor?): Int {
                val button1 = o1 ?: return 0
                val button2 = o2 ?: return 0
                return button1.getLabel().compareTo(button2.getLabel())
            }
        })
        return mutableList
    }

}